package com.iakuil.app.api.controller;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.iakuil.app.common.core.BaseController;
import com.iakuil.app.common.core.domain.Result;
import com.iakuil.app.common.core.enums.Gender;
import com.iakuil.app.common.core.enums.Results;
import com.iakuil.app.common.core.util.HashIdUtils;
import com.iakuil.app.domain.dto.cmd.UserRegister;
import com.iakuil.app.domain.entity.User;
import com.iakuil.app.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 用户会话接口
 *
 * <p>同时记录用户会话（注册、登录、注销）日志，具体实现可参考RuoYi框架。
 *
 * @author Kai
 */
@Tag(name = "会话管理", description = "用户注册、登录及注销接口")
@Slf4j
@RestController
@RequestMapping("/api/v1/user")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class LoginController extends BaseController {

    private final UserService userService;

    @Operation(summary = "用户注册", description = "新用户注册。")
    @PostMapping(value = "/register")
    public Result<Void> doSignUp(@Validated @RequestBody UserRegister param) {
        User entity = new User();
        entity.setUserName(param.getUserName());
        entity.setPassword(BCrypt.hashpw(param.getPassword()));
        entity.setNickName("用户" + HashIdUtils.encrypt(System.currentTimeMillis()));
        entity.setGender(Gender.OTHER);
        userService.checkUnique(entity);
        return success(userService.save(entity));
    }

    @Operation(summary = "用户登录", description = "用户登录。")
    @PostMapping(value = "/login")
    @Parameters({
        @Parameter(name = "username", description = "username", required = true, in = ParameterIn.QUERY, example = "harry"),
        @Parameter(name = "password", description = "password", required = true, in = ParameterIn.QUERY, example = "admin123")
    })
    public Result<SaTokenInfo> doSignIn(@RequestParam String username, @RequestParam String password) {
        User query = new User();
        query.setUserName(username);
        User user = userService.getOne(query, true);
        if (user == null || !BCrypt.checkpw(password, user.getPassword())) {
            return error(Results.UNAUTHORIZED.getCode(), "用户名或密码错误");
        }

        StpUtil.login(user.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        Result<SaTokenInfo> result = Result.success(tokenInfo);
        result.put("userId", user.getId());
        return result;
    }

    @Operation(summary = "用户注销", description = "用户注销登录。")
    @PostMapping(value = "/logout")
    public Result<SaTokenInfo> doSignOut() {
        StpUtil.logout();
        return Result.success();
    }
}
